﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace Micro.Extensions.Utilities
{
    public static class ArgCheck
    {
        /// <summary>
        /// 对象不能为null
        /// </summary>
        public static void NotNull(object argument, string argumentName, string errorMessage = null)
        {
            if (argument == null)
            {
                throw new ArgumentNullException(argumentName, errorMessage);
            }
        }

        /// <summary>
        /// 字符不能为null或空字符串
        /// </summary>
        public static void NotNullOrWhiteSpace(string argument, string argumentName, string errorMessage = null)
        {
            if (string.IsNullOrWhiteSpace(argument))
            {
                throw new ArgumentNullException(argumentName, errorMessage);
            }
        }

        /// <summary>
        /// 字符不能为null或空字符串
        /// </summary>
        public static void NotNullOrWhiteSpace(string argument, string errorMessage = null)
        {
            if (string.IsNullOrWhiteSpace(argument))
            {
                throw new ArgumentNullException(nameof(argument), errorMessage);
            }
        }

        /// <summary>
        /// 字符不能为null或空字符串，并且符合设定长度
        /// </summary>
        public static void NotNullOrWhiteSpaceAndFixedLength(string argument, string argumentName, int length)
        {
            if (string.IsNullOrWhiteSpace(argument))
            {
                throw new ArgumentNullException(argumentName);
            }

            if (argument.Length > length)
            {
                throw new ArgumentOutOfRangeException(nameof(argument), $"参数{argument}值字符串长度大于预期长度值{length}，请修改后重试！");
            }
        }

        /// <summary>
        /// 集合不为null并且大于0
        /// </summary>
        public static void NotNullAndCountGTZero<T>(IEnumerable<T> argument, string argumentName, string errorMessage = null)
        {
            if (argument == null || !argument.Any())
            {
                throw new ArgumentNullException(argumentName, errorMessage);
            }
        }

        /// <summary>
        /// 集合不为null并且大于0，并且集合的所有对象不为null或空字符串
        /// </summary>
        public static void NotNullOrWhiteSpaceAndCountGTZero<T>(IEnumerable<T> argument, string argumentName, string errorMessage = null)
        {
            var enumerable = argument as T[] ?? argument.ToArray();
            if (argument == null || !enumerable.Any())
            {
                throw new ArgumentNullException(argumentName, errorMessage);
            }

            enumerable.ToList().ForEach(a => NotNullOrWhiteSpace(a.ToString(), nameof(a)));
        }

        /// <summary>
        /// 不为负数或0
        /// </summary>
        public static void NotNegativeOrZero(TimeSpan argument, string argumentName, string errorMessage = null)
        {
            if (argument <= TimeSpan.Zero)
            {
                throw new ArgumentOutOfRangeException(argumentName, errorMessage);
            }
        }

        /// <summary>
        /// 不为负数或0
        /// </summary>
        public static void NotNegativeOrZero(int argument, string argumentName, string errorMessage = null)
        {
            if (argument <= 0)
            {
                throw new ArgumentOutOfRangeException(argumentName, errorMessage);
            }
        }

        /// <summary>
        /// 不为0
        /// </summary>
        public static void NotZero(int argument, string argumentName, string errorMessage = null)
        {
            if (argument == 0)
            {
                throw new ArgumentOutOfRangeException(argumentName, errorMessage);
            }
        }

        /// <summary>
        /// 检查List是否重复
        /// </summary>
        public static void NotValueRepeat<T>(List<T> lists)
        {
            if (lists.Distinct().Count() != lists.Count)
                throw new ArgumentException(nameof(lists), "发现重复项:" + lists.ToJson());
        }
    }
}
